Skip to content

drivers: sensor: icm45686: fix stream init and early-interrupt handling - #117394

Open
bperseghetti wants to merge 3 commits into
zephyrproject-rtos:mainfrom
CogniPilot:pr-deps-icm45686-stream
Open

drivers: sensor: icm45686: fix stream init and early-interrupt handling#117394
bperseghetti wants to merge 3 commits into
zephyrproject-rtos:mainfrom
CogniPilot:pr-deps-icm45686-stream

Conversation

@bperseghetti

@bperseghetti bperseghetti commented Aug 26, 2026

Copy link
Copy Markdown
Member

Three fixes to the ICM45686 streaming path:

  • Zero int_config before disabling interrupts in stream init. The struct was passed uninitialized to the call whose purpose is to disable every INT1 source, so stack garbage could instead enable arbitrary sources and assert a data-ready edge before the RTIO stream was armed. The APEX and trigger init paths already memset it first.

  • Ignore interrupts that arrive before a streaming submission is armed. The event handler loaded the read configuration from the submission pointer before the NULL guard, so an early data-ready edge dereferenced a NULL pointer. A driver test invokes the handler with no submission armed and confirms the interrupt is ignored. The test compiles the stream translation unit directly with stubbed bus helpers so the guard can be exercised without a bus and device instance.

  • Rate-limit the ignore-path logs. During a stall both ignore paths fire on every data-ready edge, and one warning per event floods the log backend and can starve the threads that would clear the stall. Count the dropped events instead and emit at most one summary per second carrying the suppressed counts, kept per instance so a multi-IMU system attributes each sensor separately.

Validated on NXP MCXN947 hardware with the IMU streaming at 800 Hz.

bperseghetti and others added 3 commits August 25, 2026 08:20
icm45686_stream_init passed an uninitialized int_config to
icm456xx_set_config_int, whose purpose there is to disable every INT1
source. The unwritten fields are stack garbage, so the call could
instead enable arbitrary INT1 sources and assert a data-ready edge
before the RTIO stream is armed. The APEX (icm45686.c) and trigger
(icm45686_trigger.c) init paths already memset it to INV_IMU_DISABLE
first, so do the same on the streaming path.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
icm45686_event_handler loaded read_cfg from
data->stream.iodev_sqe->sqe.iodev->data at function entry, before the
guard that checks whether iodev_sqe is NULL. A data-ready edge that
arrives before a streaming submission is armed therefore dereferenced a
NULL pointer. Handle the no-submission case in its own guard that
ignores the spurious interrupt and returns, keep the cancelled
submission path separate, and defer the read_cfg load until after both
checks.

Add a driver test that invokes the handler with no submission armed and
confirms the interrupt is ignored. The test compiles the stream
translation unit directly with stubbed bus helpers so the guard can be
exercised without a full bus and device instance, and enables
CONFIG_ICM45686_STREAM through Kconfig so the driver data layout matches
the streaming build.

Signed-off-by: James Goppert <james.goppert@gmail.com>
Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
The event handler drops an interrupt whenever a stream is already in
progress or no submission is armed. During a stall these fire on every
data-ready edge, and one warning per event floods the log backend and
can starve the threads that would clear the stall. Count the dropped
events and emit at most one summary per second so the fault stays
visible without flooding.

A summary that carries the suppressed count is used rather than a plain
rate-limited log (LOG_WRN_RATELIMIT) so the operator sees how many edges
were dropped in the interval, not just that dropping occurred. The
counters and the report deadline live in per-instance driver data so a
two-IMU system attributes and rate-limits each sensor independently
instead of aggregating them into one shared total.

An alternative that removes the busy-path re-entries outright, disabling
the DRDY interrupt on entry to ICM45686_STREAM_BUSY and re-arming it
from icm45686_stream_submit, was considered and set aside: it changes
the pulse-mode interrupt timing for every user of this driver, so it is
left for a separate change validated on hardware.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Sensors Sensors area: Tests Issues related to a particular existing or missing test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants